home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1999 March
/
EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso
/
earcd
/
utils
/
xad
/
developer
/
sources
/
clients
/
xmash.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-01-01
|
5KB
|
225 lines
#ifndef XADMASTER_XMASH_C
#define XADMASTER_XMASH_C
/* Programmheader
Name: xMash.c
Main: xadmaster
Versionstring: $VER: xMash.c 1.1 (04.02.1999)
Author: SDI
Distribution: Freeware
Description: xMash disk archiver client
1.0 05.09.98 : first version
1.1 04.02.99 : added new InfoText system
*/
#include <proto/xadmaster.h>
#include "SDI_compiler.h"
#include "xpkstuff.c"
#ifndef XADMASTERFILE
#define xMash_Client FirstClient
#define NEXTCLIENT 0
UBYTE version[] = "$VER: xMash 1.1 (04.02.1999)";
#endif
#define XMASH_VERSION 1
#define XMASH_REVISION 1
/*
structure of one xMash chunk:
UBYTE xmc_Type;
UBYTE xmc_Start
UBYTE xmc_Num;
ULONG xmc_Size;
*/
#define XMASH_INFOTEXT 0x46
#define XMASH_BANNER 0x42
#define XMASH_ARCHIVE 0x44
struct xMashHead {
UBYTE type;
UBYTE start;
UBYTE num;
};
ASM(BOOL) xMash_RecogData(REG(d0, ULONG size), REG(a0, STRPTR data),
REG(a6, struct xadMasterBase *xadMasterBase))
{
if(data[0] == 'M' && data[1] == 'S' && data[2] == 'H' &&
(data[3] == XMASH_BANNER || data[3] == XMASH_ARCHIVE || data[3] ==
XMASH_INFOTEXT))
return 1;
else
return 0;
}
ASM(LONG) xMash_GetInfo(REG(a0, struct xadArchiveInfo *ai),
REG(a6, struct xadMasterBase *xadMasterBase))
{
LONG err, lowcyl = 80, highcyl = -1;
ULONG dat[9], start = 3;
struct xadDiskInfo *xdi;
struct xadTextInfo *ti = 0;
struct xMashHead h;
if(!(xdi = (struct xadDiskInfo *) xadAllocObjectA(XADOBJ_DISKINFO, 0)))
return XADERR_NOMEMORY;
ai->xai_DiskInfo = xdi;
xdi->xdi_EntryNumber = 1;
xdi->xdi_SectorSize = 512;
xdi->xdi_Cylinders = 80;
xdi->xdi_Heads = 2;
xdi->xdi_TrackSectors = 11;
xdi->xdi_CylSectors = 22;
xdi->xdi_TotalSectors = 80 * 22;
if((err = xadHookAccess(XADAC_INPUTSEEK, 3, 0, ai))) /* skip MSH */
return err;
while(ai->xai_InPos < ai->xai_InSize && !err)
{
if(!(err = xadHookAccess(XADAC_READ, 3, &h, ai)) &&
!(err = xadHookAccess(XADAC_READ, 4, dat, ai)))
{
switch(h.type)
{
case XMASH_INFOTEXT: case XMASH_BANNER:
{
struct xadTextInfo *ti2;
if((ti2 = (struct xadTextInfo *) xadAllocObjectA(XADOBJ_TEXTINFO, 0)))
{
if(h.type == XMASH_BANNER)
ti2->xti_Flags |= XADTIF_BANNER;
err = xpkDecrunch(&ti2->xti_Text, &ti2->xti_Size, ai, xadMasterBase);
start = ai->xai_InPos;
if(!ti)
xdi->xdi_TextInfo = ti2;
else
ti->xti_Next = ti2;
ti = ti2;
}
else
err = XADERR_NOMEMORY;
break;
}
case XMASH_ARCHIVE:
if(!(err = xadHookAccess(XADAC_READ, 36, dat, ai)) &&
!(err = xadHookAccess(XADAC_INPUTSEEK, dat[1]-28, 0, ai)))
{
if(dat[8] & (1<<25))
{ /* check for password flag in every entry */
ai->xai_Flags |= XADAIF_CRYPTED;
xdi->xdi_Flags |= XADDIF_CRYPTED;
}
h.num = ((h.num+h.start) >> 1)-1;
h.start >>= 1;
if(h.start < lowcyl)
lowcyl = h.start;
if(h.num > highcyl)
highcyl = h.num;
}
break;
}
}
}
if(lowcyl <= highcyl)
{
xdi->xdi_LowCyl = lowcyl;
xdi->xdi_HighCyl = highcyl;
}
else
err = XADERR_INPUT;
if(!err)
err = xadHookAccess(XADAC_INPUTSEEK, start-ai->xai_InPos, 0, ai);
return err;
}
ASM(LONG) xMash_UnArchive(REG(a0, struct xadArchiveInfo *ai),
REG(a6, struct xadMasterBase *xadMasterBase))
{
struct xMashHead h;
LONG err = 0, u;
ULONG size, lowcyl;
STRPTR a;
struct ExecBase * SysBase = xadMasterBase->xmb_SysBase;
u = ai->xai_InPos;
lowcyl = ai->xai_LowCyl;
while(!err && lowcyl <= ai->xai_HighCyl)
{
if(!(err = xadHookAccess(XADAC_READ, 3, &h, ai)) &&
!(err = xadHookAccess(XADAC_READ, 4, &size, ai)))
{
LONG endcyl, startcyl, skipbyte;
startcyl = h.start>>1;
endcyl = ((h.start+h.num)>>1)-1;
if(endcyl < lowcyl)
err = xadHookAccess(XADAC_INPUTSEEK, size, 0, ai);
else
{
ULONG size;
if(!(err = xpkDecrunch(&a, &size, ai, xadMasterBase)))
{
skipbyte = 0;
if(startcyl < lowcyl)
skipbyte = (lowcyl-startcyl)*22*512;
if(endcyl > ai->xai_HighCyl)
endcyl = ai->xai_HighCyl;
size = (endcyl+1-lowcyl)*22*512;
err = xadHookAccess(XADAC_WRITE, size, a+skipbyte, ai);
FreeVec(a);
lowcyl = endcyl+1;
}
}
}
}
/* seek back to start */
if(!err)
err = xadHookAccess(XADAC_INPUTSEEK, u-ai->xai_InPos, 0, ai);
return err;
}
ASM(void) xMash_Free(REG(a0, struct xadArchiveInfo *ai),
REG(a6, struct xadMasterBase *xadMasterBase))
{
struct ExecBase * SysBase = xadMasterBase->xmb_SysBase;
if(ai->xai_DiskInfo)
{
struct xadTextInfo *ti, *ti2;
for(ti = ai->xai_DiskInfo->xdi_TextInfo; ti; ti = ti2)
{
ti2 = ti->xti_Next;
if(ti->xti_Text)
FreeVec(ti->xti_Text);
xadFreeObjectA(ti, 0);
}
xadFreeObjectA(ai->xai_DiskInfo, 0);
ai->xai_DiskInfo = 0; /* clear the entry */
}
}
struct xadClient xMash_Client = {
NEXTCLIENT, XADCLIENT_VERSION, 1, XMASH_VERSION, XMASH_REVISION, 3,
XADCF_DISKARCHIVER, XADCID_XMASH, "xMash", (BOOL (*)()) xMash_RecogData,
(LONG (*)()) xMash_GetInfo, (LONG (*)()) xMash_UnArchive,
(void (*)()) xMash_Free};
#endif /* XADASTER_XMASH_C */